#pragma once
#include <Rz/IObject.h>
#include <Rz/String.h>
#include <Rz/Collections/List.h>
#include "IDeviceResource.h"
#include "IBindableResource.h"
#include "IEffectProperty.h"

namespace Rz { namespace Graphics { namespace Render {

class IEffect :
	virtual public IObject,
	virtual public IDeviceResource,
	virtual public IBindableResource
	
{
	public:
		RZ_RTTI_INTERFACE(Rz::Graphics::Render, IEffect);
		RZ_RTTI_IMPLEMENTS(IObject, IDeviceResource, IBindableResource);
		RZ_RTTI_END;

		virtual void Init(const String& shader) = 0;

		virtual u32 FindUniformIndex(const String& name) const = 0;

		virtual IEffectProperty* CreateAndAddProperty(const String& name) = 0;

		virtual void AddProperty(IEffectProperty* property);
		virtual void RemoveProperty(IEffectProperty* property);

		virtual const Collections::List<Ptr<IEffectProperty>>& GetPropertyCollection() const;
		virtual Collections::List<Ptr<IEffectProperty>>& GetPropertyCollection();

		virtual IEffectProperty* GetPropertyByName(const String& name);

		virtual const IEffectProperty* GetPropertyByName(const String& name) const;

		virtual const IEffectProperty* GetPropertyByIndex(u32 index) const;
		virtual IEffectProperty* GetPropertyByIndex(u32 index);

		virtual const IEffectProperty* operator [] (const String& name) const;
		virtual IEffectProperty* operator [] (const String& name);

		virtual const IEffectProperty* operator [] (u32 index) const;
		virtual IEffectProperty* operator [] (u32 index);

	private:
		// TODO: Ptr
		Collections::List<Ptr<IEffectProperty>> _propertyCollection;
};

} } }
